package com.company.cloud.gateway.component.route.nacos;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.util.StringUtils;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.company.cloud.gateway.component.config.ZuulRouteEntity;
import com.company.cloud.gateway.component.route.AbstractDynRouteLocator;

import cn.hutool.core.bean.BeanUtil;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;

@Log4j2
public class NacosDynRouteLocator extends AbstractDynRouteLocator {

	private static final String ZUUL_DATA_ID = "zuul-routes";
	private static final String ZUUL_GROUP_ID = "ZUUL_GATEWAY";

	private NacosConfigProperties nacosConfigProperties;

	private ApplicationEventPublisher publisher;

	private NacosDynRouteLocator locator;

	@Setter
	private List<ZuulRouteEntity> zuulRouteEntities;

	public NacosDynRouteLocator(
			NacosConfigProperties nacosConfigProperties, 
			ApplicationEventPublisher publisher,
			String servletPath, ZuulProperties properties) {
		super(servletPath, properties);
		this.nacosConfigProperties = nacosConfigProperties;
		this.publisher = publisher;
		this.locator = this;
		addListener();
	}

	/**
	 * 添加Nacos监听
	 */
	private void addListener() {
		try {
//			nacosConfigProperties.configServiceInstance()
			new NacosConfigManager(nacosConfigProperties).getConfigService()
			.addListener(ZUUL_DATA_ID, ZUUL_GROUP_ID,new Listener() {
				@Override
				public void receiveConfigInfo(String configInfo) {
					 //赋值路由信息
					locator.setZuulRouteEntities(getListByStr(configInfo));
					RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(locator);
					publisher.publishEvent(routesRefreshedEvent);
				}
				@Override
				public Executor getExecutor() {
					return null;
				}
			});
		} catch (NacosException e) {
			e.printStackTrace();
		}
	}

	@Override
	public Map<String, ZuulRoute> loadDynamicRoute() {
		Map<String, ZuulRoute> routes = new LinkedHashMap<String, ZuulRoute>();
		if(zuulRouteEntities==null) {
			zuulRouteEntities=getNacosConfig();
		}
		for(ZuulRouteEntity result:zuulRouteEntities) {
			if(StringUtils.isEmpty(result.getPath()) || !result.isEnabled()) {
				continue;
			}
			ZuulRoute zuulRoute=new ZuulRoute();
			BeanUtil.copyProperties(result, zuulRoute);
	        routes.put(zuulRoute.getPath(), zuulRoute);
		}
		return routes;
	}
	
	
    private List<ZuulRouteEntity> getNacosConfig() {
        try {
            String content = nacosConfigProperties.configServiceInstance().getConfig(ZUUL_DATA_ID, ZUUL_GROUP_ID,5000);
            return getListByStr(content);
        } catch (NacosException e) {
            log.error("listenerNacos-error", e);
        }
        return new ArrayList<>(0);
    }
	
	  public List<ZuulRouteEntity> getListByStr(String content) {
	        if (StringUtils.hasText(content)) {
	            return JSONObject.parseArray(content, ZuulRouteEntity.class);
	        }
	        return new ArrayList<ZuulRouteEntity>(0);
	    }
	
	
	
	
	
	
	
	
	

}
